home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_56 / mixing.asm < prev    next >
Assembly Source File  |  1995-01-01  |  16KB  |  426 lines

  1. model large,pascal
  2.  
  3. noeffect EQU    dw offset no_effect
  4.  
  5. .DATA
  6. INCLUDE GENERAL.DEF
  7. EXTRN tickbuffer  :DWORD
  8. EXTRN post8bit    :WORD
  9. EXTRN curtick     :BYTE
  10. EXTRN curspeed    :BYTE
  11. EXTRN curline     :BYTE
  12. EXTRN BPT         :WORD
  13. EXTRN EndOfSong   :BYTE
  14. EXTRN usedchannels:BYTE
  15. EXTRN volumetableptr :DWORD
  16. EXTRN CHANNEL        :TChannel
  17. EXTRN Userate     :WORD
  18. EXTRN gvolume        :BYTE
  19. EXTRN patterndelay   :BYTE
  20. EXTRN smpEMShandle   :WORD
  21. EXTRN frameseg       :WORD
  22. EXTRN DMArealBufsize :WORD
  23. EXTRN TickBytesLeft  :WORD
  24. nextPosition      DW ?
  25. sample2calc       DW ?     ; in mono number of bytes/ in stereo number of words
  26. curchannel        DB ?
  27. calleffects       DB ?
  28.  
  29. effects            noeffect
  30.                    noeffect
  31.                    noeffect
  32.                    noeffect
  33.                    dw offset VolumeEfcts    ; effect 'D'
  34.                    dw offset Pitchdowns     ; effect 'E'
  35.                    dw offset Pitchups       ; effect 'F'
  36.                    dw offset Portamento     ; effect 'G'
  37.                    dw offset Vibrato        ; effect 'H'
  38.                    dw offset Tremor         ; effect 'I'
  39.                    dw offset Arpeggio       ; effect 'J'
  40.                    dw offset Vib_Vol        ; effect 'K'
  41.                    dw offset Port_Vol       ; effect 'L'
  42.                    noeffect
  43.                    noeffect
  44.                    noeffect
  45.                    noeffect
  46.                    dw offset Retrigg        ; effect 'Q'
  47.                    dw offset Tremolo        ; effect 'R'
  48.                    dw offset Specialsets    ; effect 'S'   ; <- for notecut/delay reasons
  49.                    noeffect
  50.                    dw offset fineVibrato    ; effect 'U'
  51.                    noeffect
  52.  
  53. vol_cmd2nd         dw offset volslidedown
  54.                    dw offset volslideup
  55.                    noeffect
  56.                    noeffect
  57. pitdwn_cmd2nd      dw offset pitchdown
  58.                    noeffect
  59.                    noeffect
  60. pitup_cmd2nd       dw offset pitchup
  61.                    noeffect
  62.                    noeffect
  63. retrig_cmd2nd      noeffect
  64.                    dw offset slddown
  65.                    dw offset use2div3
  66.                    dw offset use1div2
  67.                    dw offset sldup
  68.                    dw offset use3div2
  69.                    dw offset use2times
  70.  
  71.       ; and for all special commands :
  72. special_cmd2nd     noeffect                   ; S0? - nothin
  73.                    noeffect                   ; set filter
  74.                    noeffect                   ; set glissando
  75.                    noeffect                   ; set finetune
  76.                    noeffect                   ; set vibrato waveform
  77.                    noeffect                   ; set tremolo waveform
  78.                    noeffect                   ; does not exist
  79.                    noeffect                   ; does not exist
  80.                    noeffect                   ; maybe later (it's E8x - panning )
  81.                    noeffect                   ; does not exist
  82.                    noeffect                   ; stereo control
  83.                    noeffect                   ; Pattern loop things
  84.                    dw offset Notecut
  85.                    dw offset Notedelay
  86.                    noeffect                   ; Pattern delay
  87.                    noeffect                   ; funkrepeat
  88.  
  89. dwofs macro name, no
  90.       dw offset &name&no
  91. endm
  92.  
  93. ; stereo innerloop table:
  94. zaehler = 0
  95. st_innerloop_tbl LABEL WORD
  96. rept 32
  97.    dwofs st_inner, %zaehler
  98.    zaehler = zaehler + 1
  99. endm
  100.  
  101. ; mono innerloop table:
  102. zaehler = 0
  103. mn_innerloop_tbl LABEL WORD
  104. rept 32
  105.    dwofs mn_inner, %zaehler
  106.    zaehler = zaehler + 1
  107. endm
  108.  
  109. ENDS
  110.  
  111. .CODE
  112. .386
  113.  
  114. PUBLIC calc_stereo_tick
  115. PUBLIC calc_mono_tick
  116. EXTRN  readnewnotes
  117. EXTRN  SetupNewInst
  118. EXTRN  SetNewNote
  119.  
  120. CalcFrequStep  MACRO
  121. ; IN: ax = period
  122. ; OUT: destroys EDX,EBX
  123.  
  124.              and     eax,0ffffh      ; clear upper 16bit
  125.              xor     edx,edx
  126.              mov     dx,[Userate]
  127.              mul     edx             ; EAX = Userate*Period
  128.              mov     ebx,eax
  129.  
  130.              xor     edx,edx
  131.              mov     dx,0dah
  132.              mov     eax,77900000h   ; EDX:EAX = 1712*8363*10000h
  133.  
  134.              div     ebx
  135.  
  136.              ;        1712 * 8363 * 10000h
  137.              ; EAX = ----------------------
  138.              ;        Userate * Period
  139. ENDM
  140.  
  141. INCLUDE BORDER.INC
  142.  
  143. INCLUDE STEREO.INC
  144.  
  145. INCLUDE MONO.INC
  146.  
  147. ; for stereo and mono the same :
  148.  
  149. no_effect:     retn     ; <- sorry for this :(
  150. VolumeEfcts:   ; effect 'D'
  151.                mov       bx,ds:[channel.cmd2nd+bp]
  152.                jmp       [vol_cmd2nd+bx]
  153. volslidedown:  mov       al,ds:[channel.Parameter+bp]
  154.                and       al,0fh
  155.                sub       ds:[channel.SampleVol+bp],al
  156.                jnc       vlsdwn
  157.                mov       ds:[channel.SampleVol+bp],0
  158. vlsdwn:        retn
  159. volslideup:    mov       al,ds:[channel.Parameter+bp]
  160.                shr       al,4
  161.                add       ds:[channel.SampleVol+bp],al
  162.                cmp       ds:[channel.SampleVol+bp],64
  163.                jb        vlsup
  164.                mov       ds:[channel.SampleVol+bp],63
  165. vlsup:         mov       al,ds:[channel.SampleVol+bp]
  166.                mul       [gvolume]
  167.                shr       ax,6
  168.                mov       ds:[channel.SampleVol+bp],al
  169.                retn
  170. Pitchdowns:    ; effect 'E'
  171.                mov       bx,ds:[channel.cmd2nd+bp]
  172.                jmp       [pitdwn_cmd2nd+bx]
  173. Pitchdown:     ; we pitch down, but increase period ! (so check upper_border)
  174.                mov       ax,ds:[channel.sPeriod+bp]
  175.                mov       bl,ds:[channel.Parameter+bp]
  176.                xor       bh,bh
  177.                shl       bx,2
  178.                add       ax,bx
  179.                cmp       ax,ds:[channel.upper_border+bp]
  180.                jb        calcnewSF
  181.                mov       ax,ds:[channel.upper_border+bp]
  182. calcnewSF:     ; now calc new frequency step for this period
  183.                mov       ds:[channel.sPeriod+bp],ax
  184.                cmp       ax,0
  185.                je        donotcalc
  186.                CalcFrequStep
  187.                mov     ds:[channel.sStep+bp],EAX
  188. donotcalc:     retn
  189. Pitchups:      ; effect 'F'
  190.                mov       bx,ds:[channel.cmd2nd+bp]
  191.                jmp       [pitup_cmd2nd+bx]
  192. Pitchup:       ; we pitch up, but decrease period ! (so check lower_border)
  193.                mov       ax,ds:[channel.sPeriod+bp]
  194.                mov       bl,ds:[channel.Parameter+bp]
  195.                xor       bh,bh
  196.                shl       bx,2
  197.                sub       ax,bx
  198.                cmp       ax,ds:[channel.lower_border+bp]
  199.                ja        calcnewSF
  200.                mov       ax,ds:[channel.lower_border+bp]
  201.                jmp       calcnewSF
  202. Portamento:    ; effect 'G'
  203.                mov       bl,ds:[channel.PortPara+bp]
  204.                xor       bh,bh
  205.                shl       bx,2    ; <- use amiga slide = para*4
  206.                mov       ax,ds:[channel.sPeriod+bp]
  207.                cmp       ax,ds:[channel.wantedPeri+bp]
  208.                jg        porta_down
  209.                add       ax,bx
  210.                cmp       ax,ds:[channel.wantedPeri+bp]
  211.                jle       calcnewSF
  212.                mov       ax,ds:[channel.wantedPeri+bp]
  213.                jmp       calcnewSF
  214. porta_down:    sub       ax,bx
  215.                cmp       ax,ds:[channel.wantedPeri+bp]
  216.                jge       calcnewSF
  217.                mov       ax,ds:[channel.wantedPeri+bp]
  218.                jmp       calcnewSF
  219. Vibrato:       ; effect 'H'
  220.                cmp       ds:[channel.enabled+bp],0
  221.                je        novib
  222.                ; next position in table:
  223.                mov       al,ds:[channel.VibPara+bp]
  224.                mov       dl,al
  225.                and       dl,0fh
  226.                shr       al,4
  227.                mov       bl,ds:[channel.Tablepos+bp]
  228.                add       bl,al
  229.  
  230.                cmp       bl,64
  231.                jb        endoftest
  232.                sub       bl,64
  233. endoftest:
  234.                mov       ds:[channel.Tablepos+bp],bl
  235.                xor       bh,bh
  236.                add       bx,ds:[channel.VibTabOfs+bp]
  237.                mov       al,ds:[bx]
  238.                imul      dl
  239.                sar       ax,4
  240.                mov       bx,ds:[channel.Oldperiod+bp]
  241.                add       ax,bx
  242.                jmp       calcnewSF
  243. novib:         retn
  244. Tremor:        ; effect 'I'
  245.                retn
  246. Arpeggio:      ; effect 'J'
  247.                mov       bl,ds:[ArpegPos+bp]
  248.                xor       bh,bh
  249.                inc       bx
  250.                cmp       bx,3
  251.                jb        inside         ; Oh I love this song - INSIDE.S3M ;)
  252.                xor       bx,bx
  253. inside:        mov       ds:[ArpegPos+bp],bl
  254.                shl       bx,2
  255.                ; cool way to address Step 0,1,2 :
  256.                add       bp,bx
  257.                mov       eax,ds:[channel.step0+bp]  ; <- don't think we load here _everytime_ step0 !
  258.                sub       bp,bx
  259.                ; now use it :
  260.                mov       ds:[channel.sStep+bp],eax
  261.                retn
  262. Vib_Vol:       ; effect 'K'
  263.                ; first do volslides :
  264.                call near ptr VolumeEfcts  ; oh well I love ASM
  265.                                           ; -> JUMP ARROUND, JUMP JUMP JUMP
  266.                ; and now vibrato:
  267.                jmp       vibrato          ; that's nice ;) no need for more :)
  268. Port_Vol:      ; effect 'L'
  269.                ; first do volslides :
  270.                call near ptr VolumeEfcts
  271.                ; and portamento
  272.                jmp       portamento
  273.                retn
  274.  
  275. retrigg:       ; effect 'Q'
  276.                ; do retrigg counter ...
  277.                cmp      ds:[channel.ctick+bp],0
  278.                jz       doretrigg
  279.                dec      ds:[channel.ctick+bp]
  280.                jz       doretrigg
  281.                retn
  282. doretrigg:     mov      ds:[channel.sCurPos+bp],0
  283.                mov      al,ds:[channel.Parameter+bp]
  284.                and      al,0fh
  285.                jnz      dovolchanges
  286.                retn
  287. dovolchanges:  ; do volume change :
  288.                mov      ds:[channel.ctick+bp],al
  289.                mov      bx,ds:[channel.cmd2nd+bp]
  290.                jmp      [retrig_cmd2nd+bx]
  291. slddown:       mov      cl,ds:[channel.parameter+bp]
  292.                shr      cl,4
  293.                mov      al,1
  294.                shl      al,cl
  295.                sub      ds:[channel.SampleVol+bp],al
  296.                jnc      slddwnok
  297.                mov      ds:[channel.SampleVol+bp],0
  298. slddwnok:      retn
  299. use2div3:      ; (it's 5/8 in real life ;)
  300.                mov      al,ds:[channel.SampleVol+bp]
  301.                mov      ah,al
  302.                shl      al,2             ; al = 4*volume , ah = volume
  303.                add      al,ah            ; al = 5*volume
  304.                shr      al,3             ; al = 5*volume/8
  305.                mov      ds:[channel.SampleVol+bp],al
  306.                retn
  307. use1div2:      shr      ds:[channel.SampleVol+bp],1
  308.                retn
  309. sldup:         mov      cl,ds:[channel.parameter+bp]
  310.                shr      cl,4
  311.                mov      al,1
  312.                shl      al,cl
  313.                add      al,ds:[channel.SampleVol+bp]
  314. voltest:       cmp      al,64
  315.                jb       sldupok
  316.                mov      al,63
  317. sldupok:       mov      ds:[channel.SampleVol+bp],al
  318.                retn
  319. use3div2:      mov      al,ds:[channel.SampleVol+bp]
  320.                mov      ah,al
  321.                add      al,al            ; al = 2*volume , ah = volume
  322.                add      al,ah            ; al = 3*volume
  323.                shr      al,1             ; al = 3*volume/2
  324.                jmp      voltest
  325. use2times:     mov      al,ds:[channel.SampleVol+bp]
  326.                shl      al,1
  327.                jmp      voltest
  328. Tremolo:       ; effect 'R'
  329.                ; next position in table:
  330.                mov       al,ds:[channel.Parameter+bp]
  331.                mov       dl,al
  332.                and       dl,0fh
  333.                shr       al,4
  334.                mov       bl,ds:[channel.Tablepos+bp]
  335.                add       bl,al
  336.  
  337.                cmp       bl,64
  338.                jb        endoftest2
  339.                sub       bl,64
  340. endoftest2:
  341.                mov       ds:[channel.Tablepos+bp],bl
  342.                xor       bh,bh
  343.                add       bx,ds:[channel.TrmTabOfs+bp]
  344.                mov       al,ds:[bx]
  345.                imul      dl
  346.                sar       ax,6
  347.                mov       bl,ds:[channel.oldvolume+bp]
  348.                xor       bh,bh
  349.                add       bx,ax
  350.                cmp       bx,63
  351.                jng       ok1
  352.                mov       bl,63
  353. ok1:           cmp       bx,0
  354.                jnl       ok2
  355.                mov       bl,0
  356. ok2:           mov       ds:[channel.SampleVol+bp],bl
  357.                retn
  358.  
  359. Specialsets:   ; effect 'S'
  360.                mov      bx,ds:[channel.cmd2nd+bp]
  361.                jmp      [special_cmd2nd+bx]
  362.                retn
  363. Notecut:       dec      ds:[channel.ndTick+bp]
  364.                jz       docut
  365.                retn
  366. docut:         mov      ds:[channel.enabled+bp],0       ;disable it ...
  367.                retn
  368. Notedelay:     dec      ds:[channel.ndTick+bp]
  369.                jz       StartNewNote
  370.                retn
  371. StartNewNote:  ; Ok now we have to calc things for the new note/instr ...
  372.                ; 1. Setup Instrument
  373.                push     fs              ; segment to volumetable, but we destroy it here ...
  374.                mov      si,bp
  375.                mov      al,[channel.savInst+si]
  376.                cmp      al,00
  377.                je       nonewinst
  378.                mov      [channel.InstrNo+si],al
  379.                call near ptr SetupNewInst
  380. nonewinst:     mov      al,[channel.savNote+si]
  381.                cmp      al,0ffh
  382.                je       no_newnote
  383.                cmp      al,0feh
  384.                jne      normal_note
  385.                mov      [channel.enabled+si],0     ; stop mixing
  386.                jmp      no_newnote
  387. normal_note:   mov      [channel.enabled+si],1     ; yo do mixing
  388.                mov      [channel.Note+si],al
  389.                call near ptr SetNewNote
  390. no_newnote:    mov      al,[channel.savVol+si]
  391.                cmp      al,0ffh
  392.                je       no_vol
  393.                mul      [gvolume]
  394.                shr      ax,6
  395.                mov      [channel.SampleVol+si],al
  396. no_vol:        pop      fs
  397.                mov      ds:[channel.command+si],0       ; <- no more Notedelay
  398.                retn
  399.  
  400. fineVibrato:   ; effect 'U'
  401.                cmp       ds:[channel.enabled+bp],0
  402.                je        novib
  403.                ; next position in table:
  404.                mov       al,ds:[channel.VibPara+bp]
  405.                mov       dl,al
  406.                and       dl,0fh
  407.                shr       al,4
  408.                mov       bl,ds:[channel.Tablepos+bp]
  409.                add       bl,al
  410.  
  411.                cmp       bl,64
  412.                jb        f_endoftest
  413.                sub       bl,64
  414. f_endoftest:
  415.                mov       ds:[channel.Tablepos+bp],bl
  416.                xor       bh,bh
  417.                add       bx,ds:[channel.VibTabOfs+bp]
  418.                mov       al,ds:[bx]
  419.                imul      dl
  420.                sar       ax,8
  421.                mov       bx,ds:[channel.Oldperiod+bp]
  422.                add       ax,bx
  423.                jmp       calcnewSF
  424.  
  425. ENDS
  426. END